#include <HashedString.h>

using std::string;

void Split(const string& str, StringVec& vec, char delimiter)
{
	vec.clear();
	size_t strLen = str.size();
	if (strLen == 0)
		return;

	size_t startIndex = 0;
	size_t indexOfDel = str.find_first_of(delimiter, startIndex);
	while (indexOfDel != string::npos)
	{
		vec.push_back(str.substr(startIndex, indexOfDel-startIndex));
		startIndex=indexOfDel + 1;
		if (startIndex >= strLen)
			break;
		indexOfDel = str.find_first_of(delimiter, startIndex);
	}
	if(startIndex < strLen)
		vec.push_back(str.substr(startIndex));
}

void* HashedString::hash_name(char const* pIdentStr)
{
	unsigned long BASE = 65521L;
	unsigned long NMAX = 5552;

	#define DO1(buf,i)  {s1 += tolower(buf[i]); s2 += s1;}
	#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
	#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
	#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
	#define DO16(buf)   DO8(buf,0); DO8(buf,8);

	if (pIdentStr == NULL)
		return NULL;

	if ( strcmp( pIdentStr, kpWildcardEventType ) == 0 )
	return 0;

	unsigned long s1 = 0;
	unsigned long s2 = 0;

	for ( size_t len = strlen( pIdentStr ); len > 0 ; )
	{
		unsigned long k = len < NMAX ? len : NMAX;
		len -= k;
		while (k >= 16)
		{

			DO16(pIdentStr);
			pIdentStr += 16;
			k -= 16;
		}

		if (k != 0) do
		{
			s1 += *pIdentStr++;
			s2 += s1;
		} while (--k);

		s1 %= BASE;
		s2 %= BASE;
		}
		#pragma warning(push)
		#pragma warning(disable : 4312)

		return reinterpret_cast<void *>( (s2 << 16) | s1 );

		#pragma warning(pop)
		#undef DO1
		#undef DO2
		#undef DO4
		#undef DO8
		#undef DO16
}